import { MessageTypeEnum } from "@enum/message-type.enum";
import { createDialog } from "@utils/createDialog";
import { getDayOfWeek } from "@utils/getDate";
import { addBugWithRepeatCheck, isBugInReport, removeBugFromReport } from "@utils/getReportBugs";
import { showMessage } from "@utils/showMessage";
import { CollectedBug, getCollectInfo } from '@utils/bugCollection';
import { city, getWeather } from "@utils/getWeather";

const COMPLETED_BUG_STORAGE_KEY = "completed_bugs";

export const getQuipText = () => {
  const quip = document.querySelector('.bz_quip') as HTMLSpanElement;

  if (quip) {
    const quipTypes = [
      {
        url: 'http://api.qemao.com/api/yulu/?type=1',
        type: '毒鸡汤语录',
      },
      {
        url: 'http://api.qemao.com/api/yulu/?type=2',
        type: '祖安语录',
      },
      {
        url: 'http://api.qemao.com/api/yulu/?type=3',
        type: '社会语录',
      }
    ];

    localStorage.setItem('quipType', '0');

    const getText = async (urlObj: { url: string, type: string }) => {
      try {
        // @ts-ignore
        GM_xmlhttpRequest({
          method: 'GET',
          url: urlObj.url,
          onload: function(res: any) {
            if (res && (res.status === 200)) {
              const text = res.responseText;
              const quipType = parseInt(localStorage.getItem('quipType') ?? '0');
              const quipHtml = `
                <div class="flex-center">
                  <span class="cursor-pointer text-underline" id="quip-text">${text} (点我刷新)</span>
                  <div class="flex-center">
                    ${quipTypes.map((quip, index) => `
                      <label class="flex-center cursor-pointer">
                        <input type="radio" name="quipType" value="${index}" style="margin: 2px 4px 3px 10px" />
                        <span>${quip.type}</span>
                      </label>
                    `).join('')}
                  </div>
                </div>
              `;
              quip.innerHTML = quipHtml;
    
              const quipText = document.getElementById('quip-text') as HTMLSpanElement;
              const radios = Array.from(quip.querySelectorAll('input[type="radio"][name="quipType"]')) as HTMLInputElement[];
    
              radios.forEach((radio) => {
                if (radio.value === quipType.toString()) {
                  radio.checked = true;
                }
                radio.addEventListener('change', () => {
                  const quipType = radio.value;
                  localStorage.setItem('quipType', quipType);
                  getText(quipTypes[+quipType]);
                });
              });

              if (quipText) {
                quipText.addEventListener('click', () => {
                  getText(quipTypes[quipType]);
                });
              }
            }
          }
        });
      } catch (error) {
        console.error(error);
      }
    }

    const quipType = parseInt(localStorage.getItem('quipType') ?? '0');

    getText(quipTypes[quipType]);
  }
}

export const getWeatherText = () => {
  const queryInfo = document.querySelector('.bz_query_timestamp') as HTMLSpanElement;

  if (queryInfo) {
    queryInfo.innerHTML = '加载中...';

    // @ts-ignore
    const settingCity = () => {
      const input = document.createElement('input');
      input.style.setProperty('width', '100%');
      input.value = localStorage.getItem('city') ?? '成都';

      createDialog({
        title: '设置城市',
        bodyStyle: 'width: 400px; height: 60px',
        body: input,
        onOk: (closeDialog) => {
          const value = input.value;
          if (value) {
            localStorage.setItem('city', value);
            closeDialog();
            getWeatherUI();
          } else if (!value) {
            showMessage(MessageTypeEnum.ERROR, '请输入城市名称');
          }
        }
      })
    };

    const getWeatherUI = async () => {
      try {
        // @ts-ignore
        const res = await getWeather();

        if (!res) {
          showMessage(MessageTypeEnum.ERROR, '获取天气失败');
          return;
        }

        const now = res.results[0].now;

        if (!now) {
          return;
        }

        const divider = `<span style="display: inline-block; margin: 0px 8px;">|</span>`;
        const weatherArr = [
          `<span style="display: inline-block;">${city}
            <span id="setting-city">
              <svg viewBox="64 64 896 896" focusable="false" data-icon="setting" width="1em" height="1em" fill="currentColor" aria-hidden="true">
                <path d="M512.5 390.6c-29.9 0-57.9 11.6-79.1 32.8-21.1 21.2-32.8 49.2-32.8 79.1 0 29.9 11.7 57.9 32.8 79.1 21.2 21.1 49.2 32.8 79.1 32.8 29.9 0 57.9-11.7 79.1-32.8 21.1-21.2 32.8-49.2 32.8-79.1 0-29.9-11.7-57.9-32.8-79.1a110.96 110.96 0 00-79.1-32.8zm412.3 235.5l-65.4-55.9c3.1-19 4.7-38.4 4.7-57.7s-1.6-38.8-4.7-57.7l65.4-55.9a32.03 32.03 0 009.3-35.2l-.9-2.6a442.5 442.5 0 00-79.6-137.7l-1.8-2.1a32.12 32.12 0 00-35.1-9.5l-81.2 28.9c-30-24.6-63.4-44-99.6-57.5l-15.7-84.9a32.05 32.05 0 00-25.8-25.7l-2.7-.5c-52-9.4-106.8-9.4-158.8 0l-2.7.5a32.05 32.05 0 00-25.8 25.7l-15.8 85.3a353.44 353.44 0 00-98.9 57.3l-81.8-29.1a32 32 0 00-35.1 9.5l-1.8 2.1a445.93 445.93 0 00-79.6 137.7l-.9 2.6c-4.5 12.5-.8 26.5 9.3 35.2l66.2 56.5c-3.1 18.8-4.6 38-4.6 57 0 19.2 1.5 38.4 4.6 57l-66 56.5a32.03 32.03 0 00-9.3 35.2l.9 2.6c18.1 50.3 44.8 96.8 79.6 137.7l1.8 2.1a32.12 32.12 0 0035.1 9.5l81.8-29.1c29.8 24.5 63 43.9 98.9 57.3l15.8 85.3a32.05 32.05 0 0025.8 25.7l2.7.5a448.27 448.27 0 00158.8 0l2.7-.5a32.05 32.05 0 0025.8-25.7l15.7-84.9c36.2-13.6 69.6-32.9 99.6-57.5l81.2 28.9a32 32 0 0035.1-9.5l1.8-2.1c34.8-41.1 61.5-87.4 79.6-137.7l.9-2.6c4.3-12.4.6-26.3-9.5-35zm-412.3 52.2c-97.1 0-175.8-78.7-175.8-175.8s78.7-175.8 175.8-175.8 175.8 78.7 175.8 175.8-78.7 175.8-175.8 175.8z"></path>
              </svg>
            </span>
          </span>
          `,
          getDayOfWeek('zhou'),
          now.text,
          now.temperature + "度",
        ];
        queryInfo.innerHTML = weatherArr.map((it, index) => {
          if (index === weatherArr.length - 1) {
            return it;
          } else {
            return it + divider;
          }
        }).join('');

        const settingCityBtn = document.getElementById('setting-city');

        if (settingCityBtn) {
          settingCityBtn.addEventListener('click', settingCity);
        }
      } catch (error) {
        console.error(error);
      }
    }

    getWeatherUI();
  }
}

export default () => {
  const longFormat = document.querySelector('#long_format') as HTMLElement;
  const xml = document.querySelector('#xml') as HTMLElement;
  const timeSummary = document.querySelector('#timesummary') as HTMLElement;
  const remember = document.querySelector('#remember') as HTMLElement;
  const bzIdColumns = Array.from(document.querySelectorAll('.bz_id_column a')) as HTMLLinkElement[];
  const bzShortDescColumns = Array.from(document.querySelectorAll('.bz_short_desc_column a')) as HTMLLinkElement[];
  const buglistRows = Array.from(document.querySelectorAll('.bz_buglist tr:not(:first-child)')) as HTMLTableRowElement[];

  if (longFormat) {
    longFormat.classList.add('custom-button');
    longFormat.classList.add('plain-button');
    longFormat.style.marginLeft = '0';
  }

  if (xml) {
    xml.classList.add('custom-button');
    xml.classList.add('plain-button');
    xml.style.marginLeft = '0';
  }

  if (timeSummary) {
    timeSummary.classList.add('custom-button');
    timeSummary.classList.add('plain-button');
    timeSummary.style.marginLeft = '0';
  }

  if (remember) {
    remember.classList.add('custom-button');
    remember.classList.add('plain-button');
    remember.style.marginLeft = '0';
  }

  if (bzIdColumns) {
    bzIdColumns.forEach((node) => {
      // @ts-ignore
      const td = node.parentNode as HTMLTableCellElement
      td.style.paddingLeft = '0px';
      td.style.width = '100px';
      node.classList.add('custom-button');
      node.classList.add('plain-button');

      node.addEventListener('click', (e) => {
        e.preventDefault();
        window.open(node.href, '_blank');
      })
    })
  }

  if (bzShortDescColumns) {
    bzShortDescColumns.forEach((node) => {
      node.addEventListener('click', (e) => {
        e.preventDefault();
        window.open(node.href, '_blank');
      })
    })
  }

  if (buglistRows.length) {
    buglistRows.forEach((node, index) => {
      const bugId = bzIdColumns[index].innerText;
      const bugIdForCollection = "Bug " + bugId;
      const bugTextNode = node.querySelector(".bz_short_desc_column a") as HTMLLinkElement;
      const bugText = bugTextNode.innerText;
      const bugUrl = bugTextNode.href;
      const td = document.createElement('td');
      const reportBtn = document.createElement('span');
      const completeBtn = document.createElement('span');
      const collectionBtn = document.createElement('span');
      collectionBtn.innerText = '收藏/移除';
      completeBtn.classList.add('custom-button');
      completeBtn.innerText = '解决/移除';

      if (isBugInReport(bugId)) {
        reportBtn.classList.add('custom-button');
        reportBtn.classList.add('plain-button');
        reportBtn.innerText = '移除日报';
      } else {
        reportBtn.classList.add('custom-button');
        reportBtn.innerText = '添加日报';
      }

      if (getCollectInfo(bugIdForCollection).hasCollected) {
        collectionBtn.classList.add('custom-button');
        collectionBtn.classList.add('plain-button');
      } else {
        collectionBtn.classList.add('custom-button');
      }

      reportBtn.addEventListener('click', () => {
        try {
          if (isBugInReport(bugId)) {
            removeBugFromReport(bugId);
            reportBtn.innerText = '添加日报';
            reportBtn.classList.remove('plain-button');
          } else {
            addBugWithRepeatCheck({
              id: bugId,
              name: bzShortDescColumns[index].innerText,
              url: bzIdColumns[index].href,
            });
            reportBtn.innerText = '移除日报';
            reportBtn.classList.add('plain-button');
          }
        } catch (error) {
          showMessage(MessageTypeEnum.ERROR, '操作失败: ' + error);
        }
      })

      completeBtn.addEventListener('click', () => {
        try {
          const rowId = "b" + bugId;
          const tr = document.querySelector("#" + rowId);

          const completedBugsStr = localStorage.getItem(COMPLETED_BUG_STORAGE_KEY) ?? "";
          let completedBugs = completedBugsStr.split(";").filter(p => p);

          if(tr) {
            if(!completedBugs.includes(rowId)) {
              (tr as HTMLTableRowElement).style.setProperty("background-color", "#93e077ff");
              completedBugs.push(rowId);
              completeBtn.classList.add('plain-button');
            } else {
              completeBtn.classList.remove('plain-button');
              (tr as HTMLTableRowElement).style.removeProperty("background-color");
              for (let i = 0; i < completedBugs.length; i++) {
                const element = completedBugs[i];
                
                if(element == rowId) {
                  completedBugs.splice(i, 1);
                  break;
                }
              }
            }
            localStorage.setItem(COMPLETED_BUG_STORAGE_KEY, completedBugs.join(";"));
          }
        } catch (error) {
          showMessage(MessageTypeEnum.ERROR, '标记失败: ' + error);
        }
      })

      collectionBtn.addEventListener('click', () => {
        try {
          const {collectedBugs, hasCollected} = getCollectInfo(bugIdForCollection);

          let newBugs = {
            list: collectedBugs,
          }

          if (!hasCollected) {
            newBugs = {
              list: [...collectedBugs, { id: bugIdForCollection, title: bugText, url: bugUrl }],
            }

            collectionBtn.classList.add('plain-button');
          } else {
            newBugs = {
              list: collectedBugs.length > 0 && collectedBugs.filter((bug: CollectedBug) => bug.id !== bugIdForCollection),
            }

            collectionBtn.classList.remove('plain-button');
          }
          localStorage.setItem('collected-bugs', JSON.stringify(newBugs));
        } catch (error) {
        }
      })

      td.appendChild(reportBtn);
      td.appendChild(completeBtn);
      td.appendChild(collectionBtn);
      node.appendChild(td);

      const completedBugsStr = localStorage.getItem(COMPLETED_BUG_STORAGE_KEY) ?? "";
      let completedBugs = completedBugsStr.split(";").filter(p => p);

      if(completedBugs.includes(node.id)) {
        completeBtn.classList.add('plain-button');
        (node as HTMLTableRowElement).style.setProperty("background-color", "#93e077ff");
      }
    })
  }

  getQuipText();
  getWeatherText();
}
